package loquendo.asr.demo;

import java.io.*;

import android.util.Log;

import com.loquendo.asr.ASR;
import com.loquendo.asr.ASRCallbackManager;
import com.loquendo.asr.ASREncodedString;
import com.loquendo.asr.ASRException;
import com.loquendo.asr.ASRJNIException;
import com.loquendo.asr.ASRIniFile;
import com.loquendo.asr.ASRIniFile.ASRSection;

/**
 * It provides examples on how to use Loquendo ASR with Java 
 * 
 *
 */
public class MyCommandManager extends Thread
{
	private static final String LOGTAG = "MyCommandManager";

	private static String m_szLogFolder;
	private static String m_szTestFolder;

	public static ASREncodedString NewEncodedString(String szBuffer) throws ASRException
	{
		if (szBuffer == null) return null;
		byte[] abyInBuffer = szBuffer.getBytes();
		int nLength = abyInBuffer.length;
		byte[] abyOutBuffer = new byte[nLength + 1];
		for (int nIdx = 0; nIdx < nLength; nIdx++) abyOutBuffer[nIdx] = abyInBuffer[nIdx];
		abyOutBuffer[nLength] = 0;
		return new ASREncodedString(abyOutBuffer, "UTF-8");			
	}
	
	public static void SetLogFolder(String szLogFolder)
	{
		m_szLogFolder = szLogFolder;
		File oLogFolder = new File(m_szLogFolder);
		if (oLogFolder.exists()) 
		{
			File[] aoFileList = oLogFolder.listFiles();
			for (int nIdx = 0; nIdx < aoFileList.length; nIdx++) aoFileList[nIdx].delete();
			oLogFolder.delete();
		}
		if (!oLogFolder.mkdirs())
		{
			Log.d(LOGTAG, "Unable to create log folder '" + szLogFolder + "'.");
		}
	}

	public static void SetTestFolder(String szTestFolder)
	{
		m_szTestFolder = szTestFolder;
	}
	
	private boolean m_bOnThread;
	private boolean m_bBlocking;
	private int m_nNumOfExecutions;
	private ASR.ASRSession.ASRInstance m_oInstance;
	private ASRCallbackManager m_oCallbackManager;
	private String m_szId;
	private MyLogger m_oLogger;
	private boolean m_bRunning;
	private String m_szResults;
	
	public String getLastResults()
	{
		if(m_szResults.equals("")) m_szResults = "NO RESULTS";
		return m_szResults;
	}
	
	public void WriteLog(String szLine)
	{
		if (m_oLogger != null) m_oLogger.WriteLog(szLine);
		else Log.d(LOGTAG, szLine);
	}
	
	private void WriteException(Exception oException)
	{
		WriteLog("An exception (" + oException.getClass().getName() + ") has been thrown.");
		WriteLog(oException.getMessage());
		StackTraceElement[] aoStackTrace = oException.getStackTrace();
		for (int nIdx = 0; nIdx < aoStackTrace.length; nIdx++) WriteLog(aoStackTrace[nIdx].toString());
		Log.e(LOGTAG, "**************** EXCEPTION ****************");
		Log.e(LOGTAG, oException.getMessage());
	}
	
	public MyCommandManager(boolean bOnThread, boolean bBlocking, int nNumOfExecutions, ASR.ASRSession.ASRInstance oInstance, ASRCallbackManager oCallbackManager) throws ASRException, ASRJNIException
	{
		super();
		m_bOnThread = bOnThread;
		m_bBlocking = bBlocking;
		m_nNumOfExecutions = nNumOfExecutions;
		m_oInstance = oInstance;
		m_oCallbackManager = oCallbackManager;
		String[] aszTmp = oInstance.GetId().split("-");
		m_szId = aszTmp[aszTmp.length - 1];
		//String szLogFile = m_szLogFolder + "/" + m_szId + ".log";
		m_oLogger = null; //new MyLogger(szLogFile);
		m_bRunning = false;
	}
	
	public void Release()
	{
		if (m_oLogger != null) m_oLogger.Release();
	}
	
	public synchronized void run()
	{
		int nRetCode = 0;
		WriteLog("~~ EXECUTION on instance " + m_szId + " START ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
		for (int nIdx = 0; nIdx < m_nNumOfExecutions; nIdx++)
		{
			WriteLog("\n** ITERATION n. " + nIdx + " on instance " + m_szId + " ********************************\n");
			nRetCode = this.Recog();
			if (nRetCode < 0) break;
		}
		WriteLog("\n~~ EXECUTION on instance " + m_szId + " END ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
		m_bRunning = false;
		if (m_bOnThread) 
		{
			try { this.notify(); }
			catch(Exception oException) { WriteException(oException); }
		}
	}
	
	public synchronized void Execute()
	{
		m_bRunning = true;		
		if (m_bOnThread) 
		{
			this.start();
		}
		else run();
	}

	public synchronized void WaitForExecutionEnd()
	{
		if (m_bRunning == true) 
		{
			try { this.wait(); }
			catch(Exception oException) { WriteException(oException); }
		}
	}
	
	public ASR.ASRSession.ASRInstance GetInstance()
	{
		return m_oInstance;
	}

	public MyLogger GetLogger()
	{
		return m_oLogger;
	}
	
	public int Init() 
	{
		int nRetCode = 0;
		return nRetCode;
	}
	
	private int Recog()
	{
		WriteLog("Recog - started");

		m_bRunning = true; 

		int nRetCode = 0;
		try
		{
			//RECOGNITION: save output samples into out/out.pcm
			TestFea_Recog(m_oInstance, m_bBlocking, m_szTestFolder + "/in/123.pcm", "LIN16", m_szTestFolder + "/out/out.pcm", "OFF", "SILENT_RESTART", -1);
//			TestFea_Recog(m_oInstance, m_bBlocking, m_szTestFolder + "/in/123.pcm", "LIN16", m_szTestFolder + "/out/out.pcm", null, null, -1);
			//RECOGNITION RESULTS
			int nNumOfHypos = TestFea_RecResults(m_oInstance);
			//SEMANTIC RESULTS
			TestFea_NLPResults(m_oInstance, nNumOfHypos);
		}
		catch(ASRException oException)
		{
			WriteLog("An exception (" + oException.GetName() + ") has been thrown.");
			try {WriteLog("State: " + m_oInstance.GetState());} catch(ASRException oException2) {}
			WriteLog(oException.GetMessage());
			WriteLog(oException.GetCallStack());
			nRetCode = -1;
		}	
		catch(Exception oException)
		{
			WriteException(oException);
		}
		finally
		{
			m_bRunning = false; 
			this.notify();
		}
		WriteLog("Recog - done - exit="+nRetCode);
		return nRetCode;
	}

	private int ExecuteAllTests()
	{
		int nRetCode = 0;
		ASREncodedString eszValue = null;
		
		try
		{
			//PARAMETERS
			String[] aszKeyList =   {"EpdMode", "RecognitionClass", "ConfidenceThreshold", "EpdSensitivity", "AudioMode", "NumOfHypothesys", "Encoding", "Codepage"}; 			
			String[] aszValueList = {"OFF",     "LM_GR_BASE",       "0.5",                 "0.3",            "ALAW",      "5",               "ISO",      "1"       };
			boolean[] abGetList =   {true,      true,               true,                  true,             false,       false,             true,       true      };
			TestFea_SetParameters(m_oInstance, aszKeyList, aszValueList, abGetList);
			aszKeyList[4] = null;
			TestFea_SetParametersToDefaut(m_oInstance, aszKeyList, abGetList);
			//RO GENERATION
			
			WriteLog("GENERATE ROs");			
			//RO1
			if (m_szId.equalsIgnoreCase("ch_0"))
			{
				String[] aszKeyList1 =  {"MakeFileName", 				  "RPName"};
				Object[] aoValueList1 = {m_szTestFolder + "/in/pippo.hdr", "RP"	  };
				TestFea_SetDirectives(m_oInstance, aszKeyList1, aoValueList1);
				TestFea_GenerateRO(m_oInstance, m_bBlocking);
			}
			//RO2
			String[] aszKeyList2 =  {"GrammarFileName",                    "ROName",               "RPName"};
			Object[] aoValueList2 = {m_szTestFolder + "/in/abnf_p01.gram", "pluto_" + m_szId, "RP"    };
			TestFea_SetDirectives(m_oInstance, aszKeyList2, aoValueList2);
			TestFea_GenerateRO(m_oInstance, m_bBlocking);
			//RO3
			byte[] abyGrammarFileBuffer = {'#', 'A', 'B', 'N', 'F', ' ', '1', '.', '0', ' ', 'U', 'T', 'F', '-', '8', ';', '\n', 'l', 'a', 'n', 'g', 'u', 'a', 'g', 'e', ' ', 'i', 't', '-', 'i', 't', ';', '\n', 'p', 'u', 'b', 'l', 'i', 'c', ' ', '$', 'A', ' ', '=', ' ', 'a', ';'};			
			String[] aszKeyList3 =  {"GrammarFileName",             "GrammarFileBuffer",  "ROName",                 "RPName", "SaveSource"}; 			
			Object[] aoValueList3 = {m_szTestFolder + "/in/a.gram", abyGrammarFileBuffer, "paperino_" + m_szId, 	"RP",     "YES"       };		
			TestFea_SetDirectives(m_oInstance, aszKeyList3, aoValueList3);
			TestFea_GenerateRO(m_oInstance, m_bBlocking);
			//RO4
			String[] aszKeyList4 =  {"GrammarFileName",                    				"ROName",               "RPName"};
			Object[] aoValueList4 = {m_szTestFolder + "/in/dtmf-sequence.grxml", "dtmf1_" + m_szId, 		"RP"    };
			TestFea_SetDirectives(m_oInstance, aszKeyList4, aoValueList4);
			TestFea_GenerateRO(m_oInstance, m_bBlocking);
			//RO5
			String[] aszKeyList5 =  {"GrammarFileName",                    				"ROName",               "RPName"};
			Object[] aoValueList5 = {m_szTestFolder + "/in/includeDTMFgrammar_2.grxml", "dtmf2_" + m_szId, 		"RP"    };
			TestFea_SetDirectives(m_oInstance, aszKeyList5, aoValueList5);
			TestFea_GenerateRO(m_oInstance, m_bBlocking);
			//delete RO3
			TestFea_DeleteRO(m_oInstance, "RP/paperino_" + m_szId);
			//info RO2
			TestFea_ROInfo(m_oInstance, "RP/pluto_" + m_szId);
			
			//RECOGNITION
			//ADD RO
			String[] aszROIdList = { "rp_en-us/digits" };
			ASREncodedString[] aeszRORuleList = { null };

			TestFea_AddRO(m_oInstance, aszROIdList, aeszRORuleList, null);
			//RECOG
			TestFea_Recog(m_oInstance, m_bBlocking, m_szTestFolder + "/in/123.pcm", "LIN16", m_szTestFolder + "/out/dump.pcm", null, null, -1);
			//RECOGNITION RESULTS
			int nNumOfHypos = TestFea_RecResults(m_oInstance);
			//SEMANTIC RESULTS
			TestFea_NLPResults(m_oInstance, nNumOfHypos);
			//RECORD
			//TestFea_Record(m_oInstance, m_bBlocking, m_szTestFolder + "/in/123.pcm", "LIN16", m_szTestFolder + "/out/dump.pcm");
            
			//RECOG FROM STRING
			TestFea_RecogFromString(m_oInstance, NewEncodedString("uno"));
			TestFea_RecResults(m_oInstance);
			//FORCED SEGMENTATION
			String[] aszKeyList6 =  {"Language",	"GraphemicTranscription"	};
			Object[] aoValueList6 = {"it-it", 		NewEncodedString("uno")    	};			
			TestFea_SetDirectives(m_oInstance, aszKeyList6, aoValueList6);
			TestFea_ComputeSegmentation(m_oInstance, m_bBlocking);
			TestFea_SegmResults(m_oInstance);
			//DTMP PARSING
			String[] aszDTMFList = {"RP/dtmf1_" + m_szId,	"RP/dtmf2_" + m_szId	};
			TestFea_AddRO(m_oInstance, aszDTMFList, null, null);
			int nNumOfSolutions;
			String[] aszSymbolList1 = {"1"};
			nNumOfSolutions = TestFea_ParseDTMF(m_oInstance, aszSymbolList1);
			TestFea_DTMFResults(m_oInstance, nNumOfSolutions);
			TestFea_NLPResults(m_oInstance, nNumOfSolutions);
			String[] aszSymbolList2 = {"1", "2"};
			nNumOfSolutions = TestFea_ParseDTMF(m_oInstance, aszSymbolList2);
			TestFea_DTMFResults(m_oInstance, nNumOfSolutions);
			TestFea_NLPResults(m_oInstance, nNumOfSolutions);
			String[] aszSymbolList3 = {"1", "2", "3"};
			nNumOfSolutions = TestFea_ParseDTMF(m_oInstance, aszSymbolList3);
			TestFea_DTMFResults(m_oInstance, nNumOfSolutions);
			TestFea_NLPResults(m_oInstance, nNumOfSolutions);
			String[] aszSymbolList4 = {"4"};
			nNumOfSolutions = TestFea_ParseDTMF(m_oInstance, aszSymbolList4);
			TestFea_DTMFResults(m_oInstance, nNumOfSolutions);
			TestFea_NLPResults(m_oInstance, nNumOfSolutions);
			//GRAMMAR MANIPULATION
			TestFea_DynamicGrammars(m_oInstance, m_szTestFolder + "/in/gm1.gram", m_szTestFolder + "/out/gm1_"+ m_szId + ".gram", "ABNF", m_szTestFolder + "/out/gm1_"+ m_szId + ".ini", "RP/minni1_" + m_szId);
			TestFea_DynamicGrammars(m_oInstance, m_szTestFolder + "/in/gm2.gram", m_szTestFolder + "/out/gm2_"+ m_szId + ".gram", "ABNF", m_szTestFolder + "/out/gm2_"+ m_szId + ".ini", "RP/minni2_" + m_szId);
			TestFea_DynamicGrammars(m_oInstance, m_szTestFolder + "/in/gm3.gram", m_szTestFolder + "/out/gm3_"+ m_szId + ".gram", "ABNF", m_szTestFolder + "/out/gm3_"+ m_szId + ".ini", "RP/minni3_" + m_szId);
			TestFea_DynamicGrammars(m_oInstance, m_szTestFolder + "/in/gm4.gram", m_szTestFolder + "/out/gm4_"+ m_szId + ".gram", "ABNF", m_szTestFolder + "/out/gm4_"+ m_szId + ".ini", "RP/minni4_" + m_szId);
			TestFea_DynamicGrammars(m_oInstance, m_szTestFolder + "/in/gm5.gram", m_szTestFolder + "/out/gm5_"+ m_szId + ".gram", "ABNF", m_szTestFolder + "/out/gm5_"+ m_szId + ".ini", "RP/minni5_" + m_szId);
			TestFea_DynamicGrammars(m_oInstance, m_szTestFolder + "/in/gm6.gram", m_szTestFolder + "/out/gm6_"+ m_szId + ".gram", "ABNF", m_szTestFolder + "/out/gm6_"+ m_szId + ".ini", "RP/minni6_" + m_szId);
		}
		catch(ASRException oException)
		{
			WriteLog("An exception (" + oException.GetName() + ") has been thrown.");
			try {WriteLog("State: " + m_oInstance.GetState());} catch(ASRException oException2) {}
			WriteLog(oException.GetMessage());
			WriteLog(oException.GetCallStack());
			nRetCode = -1;
		}	
		catch(Exception oException)
		{
			WriteException(oException);
		}
		return nRetCode;
	}

	private void TestFea_Recog(ASR.ASRSession.ASRInstance oInstance, boolean bBlocking, String szAudioFile, String szAudioMode, String szAudioFileDump,
			String szFirstRecogMode, String szSecondRecogMode, int nFirstModeDuration) throws ASRException
	{
		m_szResults = "";
		if (szFirstRecogMode != null || szSecondRecogMode != null) oInstance.SetRecogMode(szFirstRecogMode, szSecondRecogMode);   
		if (nFirstModeDuration >= 0) oInstance.SwitchRecogMode(nFirstModeDuration);  		
		WriteLog("Recognition starting...");
		oInstance.SetParameter("AudioMode", szAudioMode);
		if (szAudioFileDump != null) 
		{
			oInstance.SetParameter("AudioDumpFile", szAudioFileDump);
			WriteLog("Audio dump on file: " + szAudioFileDump);
		}
		String szOperationId = oInstance.Recog(bBlocking ? "Blocking" : "NonBlocking");
		if (!bBlocking)
		{
			WriteLog("non blocking: waiting for recognition...");
			MyEventListener oEventListener = (MyEventListener)m_oCallbackManager.GetEventListener();
			oEventListener.WaitFor("EndRecog", szOperationId);
			WriteLog("non blocking: waiting for recognition ended");
		}
		WriteLog("Recognition executed!");
	}
	
	private void TestFea_Record(ASR.ASRSession.ASRInstance oInstance, boolean bBlocking, String szAudioFile, String szAudioMode, String szAudioFileDump) throws ASRException
	{
		WriteLog("Recording...");
		oInstance.SetParameter("AudioMode", szAudioMode);
		String szOperationId = oInstance.Record(bBlocking ? "Blocking" : "NonBlocking", szAudioFileDump);
		if (!bBlocking)
		{
			WriteLog("Recording started ...");
			MyEventListener oEventListener = (MyEventListener)m_oCallbackManager.GetEventListener();
			oEventListener.WaitFor("EndRecord", szOperationId);
		}
		WriteLog("Recording executed! Output stored on file: " + szAudioFileDump + ".");
	}
	
	public void TestFea_RecogFromString(ASR.ASRSession.ASRInstance oInstance, ASREncodedString eszUtterance) throws ASRException
	{
		WriteLog("Recognizing utterance: '" + eszUtterance.GetText("UTF-8") + "'.");
		oInstance.RecogFromString(eszUtterance);
		WriteLog("Recognition executed!");
	}
	
	public int TestFea_ParseDTMF(ASR.ASRSession.ASRInstance oInstance, String[] aszSymbolList) throws ASRException
	{
		int nNumOfSolutions;
		int nNumOfAlivePaths;
		WriteLog("Parsing DTMF sequence ...");
		oInstance.DTMFProvide(null);
		nNumOfSolutions = oInstance.GetNumOfDTMFSolutions();
		nNumOfAlivePaths = oInstance.GetNumOfDTMFAlivePaths();
		WriteLog("Solutions: " + nNumOfSolutions + " AlivePaths: " + nNumOfAlivePaths);
		if (aszSymbolList != null)
		{
			for(int nIdx = 0; nIdx < aszSymbolList.length; nIdx++)
			{
				String szSymbol = aszSymbolList[nIdx];
				oInstance.DTMFProvide(szSymbol);
				nNumOfSolutions = oInstance.GetNumOfDTMFSolutions();
				nNumOfAlivePaths = oInstance.GetNumOfDTMFAlivePaths();
				WriteLog("SYMBOL: " + szSymbol); 
				WriteLog("Solutions: " + nNumOfSolutions + " AlivePaths: " + nNumOfAlivePaths);
			}
		}
		oInstance.Stop();
		WriteLog("Parsing executed!");
		return nNumOfSolutions;
	}	
	
	public void TestFea_ComputeSegmentation(ASR.ASRSession.ASRInstance oInstance, boolean bBlocking) throws ASRException
	{
		WriteLog("Starting segmentation ...");		
		String szOperationId = oInstance.ComputeSegmentation(bBlocking ? "Blocking" : "NonBlocking");
		if (!bBlocking) 
		{
			MyEventListener oEventListener = (MyEventListener)m_oCallbackManager.GetEventListener();
			oEventListener.WaitFor("EndSegment", szOperationId);
		}
		WriteLog("Segmentation computed!");
	}
	
	public void TestFea_GenerateRO(ASR.ASRSession.ASRInstance oInstance, boolean bBlocking) throws ASRException
	{
		WriteLog("Starting RO generation ...");		
		String szOperationId = oInstance.GenerateRO(bBlocking ? "Blocking" : "NonBlocking");
		if (!bBlocking) 
		{
			WriteLog("Generation of RO '" + oInstance.GetDirective("ROName") + "' started ...");
			MyEventListener oEventListener = (MyEventListener)m_oCallbackManager.GetEventListener();
			oEventListener.WaitFor("EndGenerateRO", szOperationId);
		}
		WriteLog("RO '" + oInstance.GetDirective("ROName") + "' generated!");
	}

	public void TestFea_DeleteRO(ASR.ASRSession.ASRInstance oInstance, String szROIdentifier) throws ASRException
	{
		WriteLog("Starting RO deletion ...");		
		oInstance.DeleteRO(szROIdentifier);
		WriteLog("RO '" + szROIdentifier + "' deleted");		
	}
	
	public void TestFea_SetParameters(ASR.ASRSession.ASRInstance oInstance, String[] aszKeyList, String[] aszValueList, boolean[] abGetList) throws ASRException
	{
		int nIdx;
		String szKey = null;
		String szValue = null;
		boolean bGet = true;
		for (nIdx = 0; nIdx < aszKeyList.length; nIdx++)
		{
			szKey = aszKeyList[nIdx];
			szValue = aszValueList[nIdx];
			if (szKey != null) oInstance.SetParameter(szKey, szValue);
		}
		WriteLog("SET PARAMETERS");				
		for (nIdx = 0; nIdx < aszKeyList.length; nIdx++)
		{
			if (abGetList != null) bGet = abGetList[nIdx];
			if (bGet)
			{
				szKey = aszKeyList[nIdx];
				if (szKey != null) szValue = oInstance.GetParameter(szKey);
				WriteLog(szKey + " = " + szValue);
			}
		}
	}

	public void TestFea_SetParametersToDefaut(ASR.ASRSession.ASRInstance oInstance, String[] aszKeyList, boolean[] abGetList) throws ASRException
	{
		int nIdx;
		String szKey = null;
		String szValue = null;
		boolean bGet = true;
		for (nIdx = 0; nIdx < aszKeyList.length; nIdx++)
		{
			szKey = aszKeyList[nIdx];
			if (szKey != null) oInstance.SetParameterToDefault(szKey);
		}
		WriteLog("SET PARAMETERS TO DEFAULT");				
		for (nIdx = 0; nIdx < aszKeyList.length; nIdx++)
		{
			if (abGetList != null) bGet = abGetList[nIdx];
			if (bGet)
			{
				szKey = aszKeyList[nIdx];
				if (szKey != null) szValue = oInstance.GetParameter(szKey);
				WriteLog(szKey + " = " + szValue);
			}
		}
	}
	
	public void TestFea_SetDirectives(ASR.ASRSession.ASRInstance oInstance, String[] aszKeyList, Object[] aoValueList) throws ASRException
	{
		int nIdx;
		String szKey = null;
		Object oValue = null;
		oInstance.ClearDirectives();
		for (nIdx = 0; nIdx < aszKeyList.length; nIdx++)
		{
			szKey = aszKeyList[nIdx];
			oValue = aoValueList[nIdx];
			if (szKey != null) oInstance.SetDirective(szKey, oValue);
		}
		WriteLog("SET DIRECTIVES");				
		for (nIdx = 0; nIdx < aszKeyList.length; nIdx++)
		{
			szKey = aszKeyList[nIdx];
			if (szKey != null) oValue = oInstance.GetDirective(szKey);
			WriteLog(szKey + " = " + oValue);
		}
	}
	
	public void TestFea_AddRO(ASR.ASRSession.ASRInstance oInstance, String[] aszROIdentifierList, ASREncodedString[] aeszRORuleList, float[] arWeightList) throws ASRException
	{
		WriteLog("TestFea_AddRO");		
		int nIdx;
		String szValue = null;
		ASREncodedString eszValue = null;
		float rValue = (float)-1;
		if(oInstance == null) oInstance = m_oInstance;
		oInstance.ClearROs();
		for (nIdx = 0; nIdx < aszROIdentifierList.length; nIdx++)
		{
			szValue = aszROIdentifierList[nIdx];
			eszValue = (aeszRORuleList == null) ? null : aeszRORuleList[nIdx];
			rValue = (arWeightList == null) ? (float)-1 : arWeightList[nIdx];
			if (szValue != null)
			{
				if (rValue < (float)0.0)
				{
					if (eszValue == null) oInstance.AddRO(szValue);
					else oInstance.AddRO(szValue, eszValue);
					
				}
				else oInstance.AddRO(szValue, eszValue, rValue);
			}
		}
		for (nIdx = 0; nIdx < oInstance.GetNumOfAddedROs(); nIdx++)
		{
			WriteLog("RO Identifier: " + oInstance.GetAddedROIdentifier(nIdx));
			eszValue = oInstance.GetAddedRORule(nIdx);
			if (eszValue != null) WriteLog("RO Rule: " + eszValue.GetText("UTF-8"));
			else WriteLog("RO Rule: -");
		}		
		WriteLog("TestFea_AddRO - done");		
	}
	
	public void TestFea_ROInfo(ASR.ASRSession.ASRInstance oInstance, String szROIdentifier) throws ASRException
	{
		WriteLog("RO INFO");
		ASR.ASRSession.ASRInstance.ASRROInfo oROInfo = oInstance.new ASRROInfo(szROIdentifier);
		TestObj_ROInfo(oROInfo);
		oROInfo.Release();			
	}
	
	public void TestObj_ROInfo(ASR.ASRSession.ASRInstance.ASRROInfo oROInfo) throws ASRException
	{
		if (oROInfo != null)
		{
			int nIdx;
			String szValue = null;
			WriteLog("Name: " + oROInfo.GetIdentifier());
			WriteLog("Type: " + oROInfo.GetType());
			szValue = ""; 
			for (nIdx = 0; nIdx < oROInfo.GetNumOfLanguages(); nIdx++) szValue += (oROInfo.GetLanguage(nIdx) + " ");
			WriteLog("Languages: " + szValue);
			WriteLog("DefaultClass: " + oROInfo.GetDefaultClass());
			WriteLog("SemanticPresence: " + oROInfo.HasSemantic());
			WriteLog("Lookahead: " + oROInfo.GetLookahead());
			WriteLog("SWVersion: " + oROInfo.GetSWVersion());
			WriteLog("RootRule: " + oROInfo.GetRootRule().GetText("UTF-8"));
			szValue = ""; 
			for (nIdx = 0; nIdx < oROInfo.GetNumOfTopLevelRules(); nIdx++) szValue += (oROInfo.GetTopLevelRule(nIdx).GetText("UTF-8") + " ");
			WriteLog("TopLevelRules: " + szValue);
		}
	}
	
	public int TestFea_RecResults(ASR.ASRSession.ASRInstance oInstance) throws ASRException
	{
		WriteLog("RECOGNITION RESULTS");
		ASR.ASRSession.ASRInstance.ASRRecRes oRecResult = oInstance.new ASRRecRes();
		int nNumOfHypos = TestObj_RecResults(oRecResult);
		oRecResult.Release();
		return nNumOfHypos;
	}
	
	public int TestObj_RecResults(ASR.ASRSession.ASRInstance.ASRRecRes oRecResults) throws ASRException
	{
		if (oRecResults != null)
		{
			int nNumOfHypos = oRecResults.GetNumOfHypothesis();
			if (nNumOfHypos <= 0) WriteLog("No result has been produced!");
			else
			{
				WriteLog("Winner RO: " + oRecResults.GetROIdentifier() + "." + oRecResults.GetRORule().GetText("UTF-8"));
				WriteLog("CPUTime: " + oRecResults.GetCPUTime());
				WriteLog("Speech Limits: [" + oRecResults.GetSpeechStartPoint("FRAMES") + "," + oRecResults.GetSpeechEndPoint("FRAMES") + "]");
				WriteLog("Rejection: " + oRecResults.GetRejectionAdvice());
				WriteLog("SNR: " + oRecResults.GetSNR());
				try
				{
					if (oRecResults.GetAudioDumpSize() > 0)
					{
						WriteLog("AudioDumpSize: " + oRecResults.GetAudioDumpSize());
						WriteLog("AudioDumpDuration: " + oRecResults.GetAudioDumpDuration());
					}
				}
				catch(ASRException oException) {}
				try
				{
					if (oRecResults.GetRecordedFileSize() > 0)
					{
						WriteLog("AudioDumpSize: " + oRecResults.GetRecordedFileSize());
						WriteLog("AudioDumpDuration: " + oRecResults.GetRecordedFileDuration());
					}
				}
				catch(ASRException oException) {}
				for (int nHypoIdx = 0; nHypoIdx < nNumOfHypos; nHypoIdx++)
				{
					WriteLog("HYPO n. " + nHypoIdx);
					ASR.ASRSession.ASRInstance.ASRRecRes.ASRHypo oHypo = oRecResults.new ASRHypo(nHypoIdx);
					TestObj_Hypo(oHypo);
					oHypo.Release();
				}
			}
			return nNumOfHypos;
		}
		else return 0;
	}	
	
	public void TestObj_Hypo(ASR.ASRSession.ASRInstance.ASRRecRes.ASRHypo oHypo) throws ASRException
	{
		if (oHypo != null)
		{
			WriteLog("RO: " + oHypo.GetROIdentifier() + "." + oHypo.GetRORule().GetText("UTF-8"));
			WriteLog("Text: " + oHypo.GetText().GetText("UTF-8"));
			WriteLog("AcousticScore: " + oHypo.GetAcousticScore());
			WriteLog("Confidence: " + oHypo.GetConfidence ());
			for (int nWordIdx = 0; nWordIdx < oHypo.GetNumOfWords(); nWordIdx++)
			{
				WriteLog("WORD n. " + nWordIdx);
				ASR.ASRSession.ASRInstance.ASRRecRes.ASRHypo.ASRWord oWord = oHypo.new ASRWord(nWordIdx);
				TestObj_Word(oWord);
				oWord.Release();
			}
		}
	}
	
	public void TestObj_Word(ASR.ASRSession.ASRInstance.ASRRecRes.ASRHypo.ASRWord oWord) throws ASRException
	{
		if (oWord != null)
		{
			String aWord = ""+oWord.GetText().GetText("UTF-8");
			m_szResults += aWord + " ";
			WriteLog("Text: " + aWord);
			WriteLog("Language: " + oWord.GetLanguage());
			WriteLog("Speech Limits: [" + oWord.GetSpeechStartPoint("FRAMES") + "," + oWord.GetSpeechEndPoint("FRAMES") + "]");
			WriteLog("AcousticScore: " + oWord.GetAcousticScore());
			WriteLog("Confidence: " + oWord.GetConfidence ());
		}
	}
	
	
	public void TestFea_NLPResults(ASR.ASRSession.ASRInstance oInstance, int nNumOfHypos) throws ASRException
	{
		if (nNumOfHypos > 0) WriteLog("NLP RESULTS");
		for (int nHypoIdx = 0; nHypoIdx < nNumOfHypos; nHypoIdx++)
		{
			WriteLog("HYPO n. " + nHypoIdx);
			ASR.ASRSession.ASRInstance.ASRNLPRes oNLPResults = oInstance.new ASRNLPRes(nHypoIdx);
			WriteLog("NumOfInterpretations: " + oNLPResults.GetNumOfInterpretations());
			TestObj_NLPResults(oNLPResults, nHypoIdx);
			oNLPResults.Release();  			
		}	
	}
	
	public void TestObj_NLPResults(ASR.ASRSession.ASRInstance.ASRNLPRes oNLPResults, int nHypoIdx) throws ASRException 
	{
		if (nHypoIdx >= 0)
		{
			for (int nInterpretationIdx = 0; nInterpretationIdx < oNLPResults.GetNumOfInterpretations(); nInterpretationIdx++)
			{
				WriteLog("INTERPRETATION n. " + nInterpretationIdx);
				ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr oInterpretation = oNLPResults.new ASRNLPIntpr(nInterpretationIdx);
				TestObj_NLPInterpretation(oInterpretation);
				oInterpretation.Release();
			}
		}
	}

	public void TestObj_NLPInterpretation(ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr oInterpretation) throws ASRException 
	{
		if (oInterpretation != null)
		{
			ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRNLPEle oElement = null;
			oElement = oInterpretation.GetRootElemet();
			TestObj_NLPElement(oElement);
			oElement.Release();
		}
	}	
	
	public void TestObj_NLPElement(ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRNLPEle oElement) throws ASRException 
	{
		if (oElement != null)
		{
			ASREncodedString eszValue = null;
			eszValue = oElement.GetName();
			WriteLog("ELEMENT: " + ((eszValue == null) ? "-" : eszValue.GetText("UTF-8")));
			WriteLog("Type: " + oElement.GetType());
			eszValue = oElement.ToBuffer("TEXT");
			WriteLog("Description: " + ((eszValue == null) ? "-" : eszValue.GetText("UTF-8")));
			WriteLog("Confidence: " + oElement.GetConfidence());
			WriteLog("NumOfSons: " + oElement.GetNumOfSons());
			String aValue = "";
			if (oElement instanceof ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRIntNLPEle)
			{
				ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRIntNLPEle oSpecificElement = (ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRIntNLPEle)oElement;
				aValue = ""+oSpecificElement.GetValue();
				WriteLog("Value: " + aValue);		
			}
			else if (oElement instanceof ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRStringNLPEle)
			{
				ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRStringNLPEle oSpecificElement = (ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRStringNLPEle)oElement;
				eszValue = oSpecificElement.GetValue();
				aValue = ""+((eszValue == null) ? "-" : eszValue.GetText("UTF-8"));
				WriteLog("Value: " + aValue);		
			}
			else if (oElement instanceof ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRBoolNLPEle)
			{
				ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRBoolNLPEle oSpecificElement = (ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRBoolNLPEle)oElement;
				aValue = ""+oSpecificElement.GetValue();
				WriteLog("Value: " + aValue);		
			}
			else if (oElement instanceof ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRFloatNLPEle)
			{
				ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRFloatNLPEle oSpecificElement = (ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRFloatNLPEle)oElement;
				aValue = ""+oSpecificElement.GetValue();
				WriteLog("Value: " + aValue);		
			}
			else if (oElement instanceof ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRDateNLPEle)
			{
				ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRDateNLPEle oSpecificElement = (ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRDateNLPEle)oElement;
				eszValue = oSpecificElement.GetValue();
				aValue = ""+((eszValue == null) ? "-" : eszValue.GetText("UTF-8"));
				WriteLog("Value: " + aValue);		
			}
			else if (oElement instanceof ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRInvalidResNLPEle)
			{
				ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRInvalidResNLPEle oSpecificElement = (ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRInvalidResNLPEle)oElement;
				eszValue = oSpecificElement.GetValue();
				aValue = ""+((eszValue == null) ? "-" : eszValue.GetText("UTF-8"));
				WriteLog("Value: " + aValue);		
			}
			if(!aValue.equals("")) m_szResults += " ("+aValue+")";
			for (int nIdx = 0; nIdx < oElement.GetNumOfSons(); nIdx++)
			{
				ASR.ASRSession.ASRInstance.ASRNLPRes.ASRNLPIntpr.ASRNLPEle oSon = null;
				oSon = oElement.GetSon(nIdx);
				TestObj_NLPElement(oSon);
				oSon.Release();
			}
		}
	}
	
	public void TestFea_SegmResults(ASR.ASRSession.ASRInstance oInstance) throws ASRException
	{
		WriteLog("SEGMENTATION RESULTS");
		ASR.ASRSession.ASRInstance.ASRSegmRes oSegmResult = oInstance.new ASRSegmRes();
		TestObj_SegmResults(oSegmResult);
		oSegmResult.Release();
	}
	
	public void TestObj_SegmResults(ASR.ASRSession.ASRInstance.ASRSegmRes oSegmResults) throws ASRException
	{
		if (oSegmResults != null)
		{
			int nNumOfPhonemes = oSegmResults.GetNumOfPhonemes();
			if (nNumOfPhonemes <= 0) WriteLog("No result has been produced!");
			else
			{
				for (int nPhoIdx = 0; nPhoIdx < nNumOfPhonemes; nPhoIdx++)
				{
					WriteLog("PHONEME n. " + nPhoIdx);
					ASR.ASRSession.ASRInstance.ASRSegmRes.ASRPho oPhoneme = oSegmResults.new ASRPho(nPhoIdx);
					TestObj_Phoneme(oPhoneme);
					oPhoneme.Release();
				}			
			}
		}
	}		
	
	public void TestObj_Phoneme(ASR.ASRSession.ASRInstance.ASRSegmRes.ASRPho oPhoneme) throws ASRException
	{
		if (oPhoneme != null)
		{
			WriteLog("Code: " + oPhoneme.GetCode());
			WriteLog("IsStationary: " + ((oPhoneme.IsStationary()) ? "YES": "NO"));
			WriteLog("Grapheme: " + oPhoneme.GetGrapheme());
			WriteLog("Speech Limits: [" + oPhoneme.GetStartFrame() + "," + oPhoneme.GetEndFrame() + "]");
		}
	}
	
	public void TestFea_DTMFResults(ASR.ASRSession.ASRInstance oInstance, int nNumOfSolutions) throws ASRException
	{
		if (nNumOfSolutions > 0) WriteLog("DTMF RESULTS");
		for (int nSlnIdx = 0; nSlnIdx < nNumOfSolutions; nSlnIdx++)
		{
			WriteLog("SOLUTION n. " + nSlnIdx);
			ASR.ASRSession.ASRInstance.ASRDTMFRes oDTMFResults = oInstance.new ASRDTMFRes(nSlnIdx);
			TestObj_DTMFResults(oDTMFResults);
			oDTMFResults.Release();  			
		}	
	}
	
	public void TestObj_DTMFResults(ASR.ASRSession.ASRInstance.ASRDTMFRes oDTMFResults) throws ASRException 
	{
		if (oDTMFResults != null)
		{
			WriteLog("ROIdentifier: " + oDTMFResults.GetROIdentifier());
			WriteLog("RORule: " + oDTMFResults.GetRORule().GetText("UTF-8"));
		}
	}
	
	public void TestFea_DynamicGrammars(ASR.ASRSession.ASRInstance oInstance, String szInGrammar, String szOutGrammar, String szFormalism, String szOutIniFile, String szROIdentifier) throws ASRException
	{
		if (szOutIniFile == null) WriteLog("GM TEST: " + szInGrammar + " -> " + szOutGrammar);
		else WriteLog("GM TEST: " + szInGrammar + " -> " + szOutIniFile + " -> " + szOutGrammar);
		ASR.ASRSession.ASRInstance.ASRGrTree oInGrammarTree = null;
		ASR.ASRSession.ASRInstance.ASRGrTree oOutGrammarTree = null;
		ASRIniFile oIniFile = null;
		//Grammar File -> GrammarTree Object
		WriteLog("Grammar File -> GrammarTree Object");
		oInGrammarTree = oInstance.new ASRGrTree(szInGrammar);
		//GrammarTree Object -> IniFile Object
		WriteLog("GrammarTree Object -> IniFile Object");
		oIniFile = new ASRIniFile();
		TestObj_GrammarTree("Read", oInGrammarTree, oIniFile);
		oInGrammarTree.Release();
		//DEBUG: IniFile Object -> IniFile File
		if (szOutIniFile != null) 
		{
			WriteLog("IniFile Object -> IniFile File");
			oIniFile.Dump(szOutIniFile);
		}
		//IniFile Object -> GrammarTree Object
		WriteLog("IniFile Object -> GrammarTree Object");
		oOutGrammarTree = oInstance.new ASRGrTree(szOutGrammar);
		TestObj_GrammarTree("Write", oOutGrammarTree, oIniFile);
		oIniFile.Release();
		//GrammarTree Object -> Grammar Buffer
		WriteLog("GrammarTree Object -> Grammar Buffer");
		byte[] abyOutBuffer = oOutGrammarTree.Dump(szFormalism);
		oOutGrammarTree.Release();
		//Grammar Buffer -> Grammar File
		WriteLog("Grammar Buffer -> Grammar File");
		RandomAccessFile oOutFile = null;
		try { oOutFile = new RandomAccessFile(szOutGrammar, "rw"); }
		catch(Exception oException) { WriteLog("Unable to open file '" + szOutGrammar + "' for writing."); }
		try { oOutFile.writeBytes(new String(abyOutBuffer)); }
		catch(Exception oException) {WriteLog("Unable to write on file '" + szOutGrammar + "'."); }
		try { oOutFile.close(); }
		catch(Exception oException) {WriteLog("Unable to close the file '" + szOutGrammar + "'."); }
		//GrammarTree Object -> Grammar RO
		if (szROIdentifier != null)
		{
			String[] aszKeyList =  {"RPName", "ROName"}; 			
			String[] aszValueList = szROIdentifier.split("\\/"); 		
			TestFea_SetDirectives(oInstance, aszKeyList, aszValueList);
			TestFea_GenerateRO(oInstance, true);
		}
		else oInstance.Stop();		
	}
	
	public void TestObj_GrammarTree(String szFea, ASR.ASRSession.ASRInstance.ASRGrTree oGrammarTree, ASRIniFile oIniFile) throws ASRException
	{
		if (szFea.equalsIgnoreCase("Read"))
		{
			oGrammarTree.Load();
			ASR.ASRSession.ASRInstance.ASRGrTree.ASRNode oRootNode = oGrammarTree.GetRootNode();
			TestObj_Node("Read", oRootNode, oIniFile, null);
		}
		else if (szFea.equalsIgnoreCase("Write"))
		{
			ASR.ASRSession.ASRInstance.ASRGrTree.ASRNode oRootNode = oGrammarTree.GetRootNode();
			TestObj_Node("Write", oRootNode, oIniFile, null);
		}
		else if (szFea.equalsIgnoreCase("Delete"))
		{
		}
	}
	
	public void TestObj_Node(String szFea, ASR.ASRSession.ASRInstance.ASRGrTree.ASRNode oNode, ASRIniFile oIniFile, ASRSection oSection) throws ASRException
	{
		//WriteLog("Testing Node ...");
		ASRSection oNewSection = null;
		String szType;
		ASR.ASRSession.ASRInstance.ASRGrTree.ASRNode oChild = null;
		if (szFea.equalsIgnoreCase("Read"))
		{
			szType = oNode.GetType();
			//WriteLog("Type: " + szType);
			if (szType != null && !szType.equalsIgnoreCase("") && !szType.equalsIgnoreCase("Root"))
			{
				oNewSection = oIniFile.new ASRSection(szType);
				if (oSection == null) oIniFile.InsertSection(oNewSection);
				else oSection.InsertSubSection(oNewSection);
				if (szType.equalsIgnoreCase("Grammar")) TestObj_GrammarNode("Read", oNode, oNewSection);
				else if (szType.equalsIgnoreCase("SemanticAttach")) TestObj_SemanticAttachNode("Read", oNode, oNewSection);
				else if (szType.equalsIgnoreCase("Lexicon")) TestObj_LexiconNode("Read", oNode, oNewSection);
				else if (szType.equalsIgnoreCase("Rule")) TestObj_RuleNode("Read", oNode, oNewSection);
				else if (szType.equalsIgnoreCase("Token")) TestObj_TokenNode("Read", oNode, oNewSection);
				else if (szType.equalsIgnoreCase("RuleRef")) TestObj_RuleRefNode("Read", oNode, oNewSection);
				else if (szType.equalsIgnoreCase("SpecialRuleRefGarbage") || szType.equalsIgnoreCase("SpecialRuleRefNull") || szType.equalsIgnoreCase("SpecialRuleRefVoid")) TestObj_SpecialRuleRefNode("Read", oNode, oNewSection);
				else if (szType.equalsIgnoreCase("Alternative")) TestObj_AlternativeNode("Read", oNode, oNewSection);
				else if (szType.equalsIgnoreCase("Sequence")) TestObj_SequenceNode("Read", oNode, oNewSection);
			}
			//WriteLog("Testing Childs ...");
			oChild = oNode.GetChild("FIRST", "UsefulToCompile", true);
			while (oChild != null)
			{
				TestObj_Node("Read", oChild, oIniFile, oNewSection);
				oChild = oNode.GetChild("NEXT", "UsefulToCompile", true);
			}
			//WriteLog("Childs Test Ended!");			
			if (oNewSection != null) oNewSection.Release();
		}
		else if (szFea.equalsIgnoreCase("Write"))
		{
			if (oSection == null) oSection = oIniFile.GetFirstSection();
			szType = oSection.GetDescription();
			//WriteLog("Type: " + szType);
			if (szType != null && !szType.equalsIgnoreCase(""))
			{
				if (szType.equalsIgnoreCase("Grammar")) TestObj_GrammarNode("Write", oNode, oSection);
				else if (szType.equalsIgnoreCase("SemanticAttach")) TestObj_SemanticAttachNode("Write", oNode, oSection);
				else if (szType.equalsIgnoreCase("Lexicon")) TestObj_LexiconNode("Write", oNode, oSection);
				else if (szType.equalsIgnoreCase("Rule")) TestObj_RuleNode("Write", oNode, oSection);
				else if (szType.equalsIgnoreCase("Token")) TestObj_TokenNode("Write", oNode, oSection);
				else if (szType.equalsIgnoreCase("RuleRef")) TestObj_RuleRefNode("Write", oNode, oSection);
				else if (szType.equalsIgnoreCase("SpecialRuleRefGarbage") || szType.equalsIgnoreCase("SpecialRuleRefNull") || szType.equalsIgnoreCase("SpecialRuleRefVoid")) TestObj_SpecialRuleRefNode("Write", oNode, oSection);
				else if (szType.equalsIgnoreCase("Alternative")) TestObj_AlternativeNode("Write", oNode, oSection);
				else if (szType.equalsIgnoreCase("Sequence")) TestObj_SequenceNode("Write", oNode, oSection);
			}
			oChild = oNode.GetChild("CURRENT", "UsefulToCompile", false);
			//WriteLog("Testing Childs ...");
			oNewSection = oSection.GetFirstSubSection();
			while (oNewSection != null)
			{
				TestObj_Node("Write", oChild, oIniFile, oNewSection);
				oNewSection = oNewSection.GetNext();
			}
			//WriteLog("Childs Test Ended!");			
		}
		//WriteLog("Node Test Ended!");
	}

	public void QuickInsertEntry(ASRIniFile.ASRSection oSection, String szKey, String szValue) throws ASRException
	{
		if (szValue != null) oSection.InsertEntry(szKey, szValue);
	}	

	public void QuickInsertEncodedEntry(ASRIniFile.ASRSection oSection, String szKey, ASREncodedString eszValue) throws ASRException
	{
		if (eszValue != null) oSection.InsertEntry(szKey, (String)eszValue.GetText("UTF-8"));		
	}	
	
	public String QuickGetEntry(ASRIniFile.ASRSection oSection, String szKey) throws ASRException
	{
		ASRIniFile.ASRSection.ASREntry oEntry = null;
		String szValue = null;
		oEntry = oSection.GetFirstEntry(szKey);
		if (oEntry != null) szValue = oEntry.GetValue();
		return szValue;
	}

	public ASREncodedString QuickGetEncodedEntry(ASRIniFile.ASRSection oSection, String szKey) throws ASRException
	{
		return NewEncodedString(QuickGetEntry(oSection, szKey));
	}
	
	public void TestObj_GrammarNode(String szFea, ASR.ASRSession.ASRInstance.ASRGrTree.ASRNode oNode, ASRSection oSection) throws ASRException
	{
		ASR.ASRSession.ASRInstance.ASRGrTree.ASRGrammarNode oSpecificNode;
		String szMode;
		String szLanguage;
		String szBaseUri;
		String szTagFormat;  
		if (szFea.equalsIgnoreCase("Read"))
		{
			oSpecificNode = (ASR.ASRSession.ASRInstance.ASRGrTree.ASRGrammarNode)oNode;
			szMode = oSpecificNode.GetMode();
			szLanguage = oSpecificNode.GetLanguage();
			szBaseUri = oSpecificNode.GetBaseUri();
			szTagFormat = oSpecificNode.GetTagFormat();  
			ASREncodedString eszRootRule = oSpecificNode.GetRootRule();
			QuickInsertEntry(oSection, "Mode", szMode);
			QuickInsertEntry(oSection, "Language", szLanguage);
			QuickInsertEntry(oSection, "BaseUri", szBaseUri);
			QuickInsertEntry(oSection, "TagFormat", szTagFormat);
			QuickInsertEncodedEntry(oSection, "RootRule", eszRootRule);		
		}
		else if (szFea.equalsIgnoreCase("Write"))
		{
			ASR.ASRSession.ASRInstance.ASRGrTree oGrammarTree = oNode.GetGrammarTree();
			szMode = QuickGetEntry(oSection, "Mode");
			szLanguage = QuickGetEntry(oSection, "Language");
			szBaseUri = QuickGetEntry(oSection, "BaseUri");
			szTagFormat = QuickGetEntry(oSection, "TagFormat");
			oSpecificNode = oGrammarTree.new ASRGrammarNode(szMode, szLanguage, szBaseUri, szTagFormat);
			oNode.InsertChild(oSpecificNode, "LAST");
			oSpecificNode.Release();
		}
	}
	
	public void TestObj_SemanticAttachNode(String szFea, ASR.ASRSession.ASRInstance.ASRGrTree.ASRNode oNode, ASRSection oSection) throws ASRException
	{
		ASR.ASRSession.ASRInstance.ASRGrTree.ASRSemanticAttachNode oSpecificNode;
		ASREncodedString eszText;
		if (szFea.equalsIgnoreCase("Read"))
		{
			oSpecificNode = (ASR.ASRSession.ASRInstance.ASRGrTree.ASRSemanticAttachNode)oNode;
			eszText = oSpecificNode.GetText();
			QuickInsertEncodedEntry(oSection, "Text", eszText);		
		}
		else if (szFea.equalsIgnoreCase("Write"))
		{
			ASR.ASRSession.ASRInstance.ASRGrTree oGrammarTree = oNode.GetGrammarTree();
			eszText = QuickGetEncodedEntry(oSection, "Text");
			oSpecificNode = oGrammarTree.new ASRSemanticAttachNode(eszText);
			oNode.InsertChild(oSpecificNode, "LAST");
			oSpecificNode.Release();
		}
	}
	
	public void TestObj_LexiconNode(String szFea, ASR.ASRSession.ASRInstance.ASRGrTree.ASRNode oNode, ASRSection oSection) throws ASRException
	{
		ASR.ASRSession.ASRInstance.ASRGrTree.ASRLexiconNode oSpecificNode;
		String szUri;
		String szMimeType;  
		if (szFea.equalsIgnoreCase("Read"))
		{
			oSpecificNode = (ASR.ASRSession.ASRInstance.ASRGrTree.ASRLexiconNode)oNode;
			szUri = oSpecificNode.GetUri();
			szMimeType = oSpecificNode.GetMimeType();  
			QuickInsertEntry(oSection, "Uri", szUri);
			QuickInsertEntry(oSection, "MimeType", szMimeType);
		}
		else if (szFea.equalsIgnoreCase("Write"))
		{
			ASR.ASRSession.ASRInstance.ASRGrTree oGrammarTree = oNode.GetGrammarTree();
			szUri = QuickGetEntry(oSection, "Uri");
			szMimeType = QuickGetEntry(oSection, "MimeType");
			oSpecificNode = oGrammarTree.new ASRLexiconNode(szUri, szMimeType);
			oNode.InsertChild(oSpecificNode, "LAST");
			oSpecificNode.Release();
		}
	}
	
	public void TestObj_RuleNode(String szFea, ASR.ASRSession.ASRInstance.ASRGrTree.ASRNode oNode, ASRSection oSection) throws ASRException
	{
		ASR.ASRSession.ASRInstance.ASRGrTree.ASRRuleNode oSpecificNode;
		ASREncodedString eszName;
		String szScope;  
		if (szFea.equalsIgnoreCase("Read"))
		{
			oSpecificNode = (ASR.ASRSession.ASRInstance.ASRGrTree.ASRRuleNode)oNode;
			eszName = oSpecificNode.GetName();
			szScope = oSpecificNode.GetScope();  
			QuickInsertEncodedEntry(oSection, "Name", eszName);		
			QuickInsertEntry(oSection, "Scope", szScope);
		}
		else if (szFea.equalsIgnoreCase("Write"))
		{
			ASR.ASRSession.ASRInstance.ASRGrTree oGrammarTree = oNode.GetGrammarTree();
			eszName = QuickGetEncodedEntry(oSection, "Name");			
			szScope = QuickGetEntry(oSection, "Scope");
			oSpecificNode = oGrammarTree.new ASRRuleNode(eszName, szScope);
			oNode.InsertChild(oSpecificNode, "LAST");
			oSpecificNode.Release();
		}
	}
	
	public void TestObj_TokenNode(String szFea, ASR.ASRSession.ASRInstance.ASRGrTree.ASRNode oNode, ASRSection oSection) throws ASRException
	{
		ASR.ASRSession.ASRInstance.ASRGrTree.ASRTokenNode oSpecificNode;
		float rWeight;
		String szLanguage;
		ASREncodedString eszText;
		ASREncodedString eszSimpleValue;
		if (szFea.equalsIgnoreCase("Read"))
		{
			oSpecificNode = (ASR.ASRSession.ASRInstance.ASRGrTree.ASRTokenNode)oNode;
			rWeight = oSpecificNode.GetWeight();
			szLanguage = oSpecificNode.GetLanguage();
			eszText = oSpecificNode.GetText();
			eszSimpleValue = oSpecificNode.GetSimpleValue();
			oSection.InsertEntry("Weight", "" + rWeight);
			QuickInsertEntry(oSection, "Language", szLanguage);
			QuickInsertEncodedEntry(oSection, "Text", eszText);		
			QuickInsertEncodedEntry(oSection, "SimpleValue", eszSimpleValue);		
		}
		else if (szFea.equalsIgnoreCase("Write"))
		{
			ASR.ASRSession.ASRInstance.ASRGrTree oGrammarTree = oNode.GetGrammarTree();
			rWeight = (new Float(QuickGetEntry(oSection, "Weight"))).floatValue();
			szLanguage = QuickGetEntry(oSection, "Language");
			eszText = QuickGetEncodedEntry(oSection, "Text");
			eszSimpleValue = QuickGetEncodedEntry(oSection, "SimpleValue");
			oSpecificNode = oGrammarTree.new ASRTokenNode(rWeight, szLanguage, eszText, eszSimpleValue);
			oNode.InsertChild(oSpecificNode, "LAST");
			oSpecificNode.Release();
		}
	}
	
	public void TestObj_RuleRefNode(String szFea, ASR.ASRSession.ASRInstance.ASRGrTree.ASRNode oNode, ASRSection oSection) throws ASRException
	{
		ASR.ASRSession.ASRInstance.ASRGrTree.ASRRuleRefNode oSpecificNode;
		float rWeight;
		ASREncodedString eszRule;
		String szExternalGrammar;  
		String szMimeType;  
		if (szFea.equalsIgnoreCase("Read"))
		{
			oSpecificNode = (ASR.ASRSession.ASRInstance.ASRGrTree.ASRRuleRefNode)oNode;
			rWeight = oSpecificNode.GetWeight();
			eszRule = oSpecificNode.GetRule();
			szExternalGrammar = oSpecificNode.GetExternalGrammar();  
			szMimeType = oSpecificNode.GetMimeType();  
			oSection.InsertEntry("Weight", "" + rWeight);
			QuickInsertEncodedEntry(oSection, "Rule", eszRule);		
			QuickInsertEntry(oSection, "ExternalGrammar", szExternalGrammar);
			QuickInsertEntry(oSection, "MimeType", szMimeType);
		}
		else if (szFea.equalsIgnoreCase("Write"))
		{
			ASR.ASRSession.ASRInstance.ASRGrTree oGrammarTree = oNode.GetGrammarTree();
			rWeight = (new Float(QuickGetEntry(oSection, "Weight"))).floatValue();
			eszRule = QuickGetEncodedEntry(oSection, "Rule");
			szExternalGrammar = QuickGetEntry(oSection, "ExternalGrammar");
			szMimeType = QuickGetEntry(oSection, "MimeType");
			oSpecificNode = oGrammarTree.new ASRRuleRefNode(rWeight, eszRule, szExternalGrammar, szMimeType);
			oNode.InsertChild(oSpecificNode, "LAST");
			oSpecificNode.Release();
		}
	}
	
	public void TestObj_SpecialRuleRefNode(String szFea, ASR.ASRSession.ASRInstance.ASRGrTree.ASRNode oNode, ASRSection oSection) throws ASRException
	{
		ASR.ASRSession.ASRInstance.ASRGrTree.ASRSpecialRuleRefNode oSpecificNode;
		float rWeight;
		String szName;
		if (szFea.equalsIgnoreCase("Read"))
		{
			oSpecificNode = (ASR.ASRSession.ASRInstance.ASRGrTree.ASRSpecialRuleRefNode)oNode;
			rWeight = oSpecificNode.GetWeight();
			szName = oSpecificNode.GetName();  
			QuickInsertEntry(oSection, "Weight", "" + rWeight);
			QuickInsertEntry(oSection, "Name", szName);
		}
		else if (szFea.equalsIgnoreCase("Write"))
		{
			ASR.ASRSession.ASRInstance.ASRGrTree oGrammarTree = oNode.GetGrammarTree();
			rWeight = (new Float(QuickGetEntry(oSection, "Weight"))).floatValue();
			szName = QuickGetEntry(oSection, "Name");
			oSpecificNode = oGrammarTree.new ASRSpecialRuleRefNode(rWeight, szName);
			oNode.InsertChild(oSpecificNode, "LAST");
			oSpecificNode.Release();
		}
	}	

	public void TestObj_AlternativeNode(String szFea, ASR.ASRSession.ASRInstance.ASRGrTree.ASRNode oNode, ASRSection oSection) throws ASRException
	{
		ASR.ASRSession.ASRInstance.ASRGrTree.ASRAlternativeNode oSpecificNode;
		float rWeight;
		String szLanguage;
		if (szFea.equalsIgnoreCase("Read"))
		{
			oSpecificNode = (ASR.ASRSession.ASRInstance.ASRGrTree.ASRAlternativeNode)oNode;
			rWeight = oSpecificNode.GetWeight();
			szLanguage = oSpecificNode.GetLanguage();
			QuickInsertEntry(oSection, "Weight", "" + rWeight);
			QuickInsertEntry(oSection, "Language", szLanguage);
		}
		else if (szFea.equalsIgnoreCase("Write"))
		{
			ASR.ASRSession.ASRInstance.ASRGrTree oGrammarTree = oNode.GetGrammarTree();
			rWeight = (new Float(QuickGetEntry(oSection, "Weight"))).floatValue();
			szLanguage = QuickGetEntry(oSection, "Language");
			oSpecificNode = oGrammarTree.new ASRAlternativeNode(rWeight, szLanguage);
			oNode.InsertChild(oSpecificNode, "LAST");
			oSpecificNode.Release();
		}
	}
	
	public void TestObj_SequenceNode(String szFea, ASR.ASRSession.ASRInstance.ASRGrTree.ASRNode oNode, ASRSection oSection) throws ASRException
	{
		ASR.ASRSession.ASRInstance.ASRGrTree.ASRSequenceNode oSpecificNode;
		float rWeight;
		String szLanguage;
		int nMinNumOfRepetitions;
		int nMaxNumOfRepetitions;
		float rRepetitionProbability;
		if (szFea.equalsIgnoreCase("Read"))
		{
			oSpecificNode = (ASR.ASRSession.ASRInstance.ASRGrTree.ASRSequenceNode)oNode;
			rWeight = oSpecificNode.GetWeight();
			szLanguage = oSpecificNode.GetLanguage();
			nMinNumOfRepetitions = oSpecificNode.GetMinNumOfRepetitions();
			nMaxNumOfRepetitions = oSpecificNode.GetMaxNumOfRepetitions();
			rRepetitionProbability = oSpecificNode.GetRepetitionProbability();
			oSection.InsertEntry("Weight", "" + rWeight);
			QuickInsertEntry(oSection, "Language", szLanguage);
			QuickInsertEntry(oSection, "MinNumOfRepetitions", "" + nMinNumOfRepetitions);
			QuickInsertEntry(oSection, "MaxNumOfRepetitions", "" + nMaxNumOfRepetitions);
			QuickInsertEntry(oSection, "RepetitionProbability", "" + rRepetitionProbability);
		}
		else if (szFea.equalsIgnoreCase("Write"))
		{
			ASR.ASRSession.ASRInstance.ASRGrTree oGrammarTree = oNode.GetGrammarTree();
			rWeight = (new Float(QuickGetEntry(oSection, "Weight"))).floatValue();
			szLanguage = QuickGetEntry(oSection, "Language");
			nMinNumOfRepetitions = (new Integer(QuickGetEntry(oSection, "MinNumOfRepetitions"))).intValue();
			nMaxNumOfRepetitions = (new Integer(QuickGetEntry(oSection, "MaxNumOfRepetitions"))).intValue();
			rRepetitionProbability = (new Float(QuickGetEntry(oSection, "RepetitionProbability"))).floatValue();
			oSpecificNode = oGrammarTree.new ASRSequenceNode(rWeight, szLanguage, nMinNumOfRepetitions, nMaxNumOfRepetitions, rRepetitionProbability);
			oNode.InsertChild(oSpecificNode, "LAST");
			oSpecificNode.Release();
		}
	}	
}

